<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>待办事项列表-组件通信练习</title>
    <style>
    .tabs button{
        margin-top: 10px;
    }
    li{
      background-color: skyblue;
      line-height: 20px;
      margin: 10px;

    }
    li>button{
        float:right
    }
    </style>
</head>
<body>
   
    <div id="app">
        <!-- 自定义标签todo-header -->
        <todo-header> 
            <!-- 给h2标签添加一个slot属性，title是命名插槽的名字 -->
            <h2 slot="title">TodoList</h2>
            <!-- 为了区别多个slot插槽修改部分，这可用新版中的v-slot 指令，可简写#，需要注意的是，他只能在template标签或者组件定义时使用 ，属性值为命名插槽的名字-->
            <template v-slot:subtitle>
                <h3>Todo......</h3>
            </template>
        </todo-header>
        <!-- （自定义事件）自定义标签todo-input,@是v-on的简写，绑定一个自定义属性add,属性值是实例化对象里面methods里面的添加列表项的名字 -->
        <todo-input @add="addTodoItem"></todo-input>
        <!-- 自定义标签todo-list,:是v-bind的简写，动态绑定一个属性list,属性值是构造的那个数组对象属性 -->
        <todo-list :list="todos"></todo-list>
    </div>
<!-- 引入vue.js文件 -->
    <script src="./lib/vue.js"></script>

    <script>
        //定义一个TodoHeader组件的选项对象
        const todoHeaderOptions = {
            template:`
            <div>
                <slot name="title">
                     <h1>待办事项列表</h1>
                </slot>
                <slot name="subtitle">
                     <h2>副标题</h2>
                </slot>
            </div>    
            `
        }//template:模板，里面放dom操作元素的代码，h1和和h2分别用命名插槽slot标签包裹，并分别命名
    
    //定义一个TodoInput组件的选项对象
        const todoInputOptions = {
            template:`
              <div>
                 <input placeholder="请输入新待办事项" 
                   v-model="inputValue"/>
                <button @click="handleAdd">添加</button>
              </div>
            `,//v-modle语法糖，在表单<input><textarea><select>元素上创建双向数据绑定
            data(){//组件中的data必须是函数结构，并返回一个对象，因为如果把data设计为普通对象，则多个组件实例都引用到的是同一个对象，当其中某一个组件实例修改数据后，其他组件实例会相应受影响，与实际需求有差异
                return{
                    inputValue:''//返回后清空
                }
            },
            methods:{//方法
                handleAdd(){//处理程序：将输入框中的文本传递给父组件
                //采用父子组件通信方式中的子传父方式传递信息，触发$emit在父组件中绑定的事件并传递参数
                    this.$emit('add',this.inputValue)

                    this.inputValue=''//清空文本框
                }
            }
        }
  //定义一个TodoItem组件的选项对象
        const todoItemOptions = {
            template:`
              <li>{{id}}-{{title}}-{{completed}} 
                  <button>删除</button>
              </li>
            `,
            props:{//采用的是父子组件通信中父传子方式的props属性传递可是数组，也可是对象，实现属性的验证
                id:Number, //验证ID为数值型
                title:{//验证title类型为字符型，默认为待办事项文字
                    type:String,
                    default:'待办事项'
                },
                completed:{//完成属性
                    type:Boolean,//验证若完成类型为布尔值
                    required:true//获取的为争取的值为true
                }
            }
        }

// 定义一个TodoList组件的选项对象
        const todoListOptions = {
            template:`
               <div>
                  <div class="tabs">
                    <button>所有</button>
                  </div>

                  <ul>
                    <todo-item
                      v-for="todo in list"
                      :id="todo.id"
                      :title="todo.title"
                      :completed="todo.completed"
                      ></todo-item>
                  </ul>
                </div>
            `,//v-for列表循环，可用于循环遍历数组的每个元素或对象的每个属性(todo对象的每个属性，list遍历对象名)
            components:{//局部注册组件，只能在其父组件内部使用
            //组件名：组件选项对象
                TodoItem:todoItemOptions
            },
            props:['list'],//属性传递数组，声明当前组件可接收的属性
        }

// 新建Vue实例化对象App
        new Vue({
            el:'#app',//element,视图，把dom事件关联起来
            components:{//局部注册组件
                TodoHeader:todoHeaderOptions,
                TodoInput:todoInputOptions,
                TodoList:todoListOptions
            },
            data:{//数据
                todos:[//构造一个数组对象属性
                    {
                        id:1,
                        titlt:'复习Htnl',
                        completed:true//完成为true
                    },
                    {
                        id:2,
                        title:'我真傻，真的，我命名之三',
                        completed:false//完成为false
                    }
                ]
            },
            methods:{//方法
                addTodoItem(title){//添加列表项，属性
                    this.todos.push({//在最后一项添加
                        id: (Math.random()).toFixed(2),//随机生成一个ID数并保留两位小数
                        title,
                        completed:false//未完成
                    })
                }
            }
        })
    
    </script>
</body>
</html>